from django.db import models
from django.utils import timezone
from django.contrib.auth import authenticate
from django.contrib.auth.models import (
    AbstractBaseUser,
    BaseUserManager,
    PermissionsMixin,
    Group,
)
from django.conf import settings
from common.models import BaseModel

USER_TYPE = (
    ("common", "普通角色"),
    ("mangage", "管理角色"),
)

SEX = (
    ("male", "男"),
    ("female", "女"),
    ("other", "未知"),
)


# 用户权限表
class Permission(models.Model):
    parent = models.ForeignKey(
        "self",
        null=True,
        blank=True,
        related_name="children",
        on_delete=models.PROTECT,
        verbose_name="所属父级权限",
    )
    code = models.CharField(max_length=255, unique=True, verbose_name="权限唯一CODE代码")
    name = models.CharField(max_length=64, verbose_name="权限名称")
    intro = models.CharField(max_length=255, null=True, blank=True, verbose_name="权限介绍")
    category = models.CharField(
        max_length=255, null=True, blank=True, verbose_name="权限类别"
    )

    # 状态信息
    creator = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.PROTECT,
        verbose_name="创建人",
        related_name="permission_creator",
    )
    created = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    modifiered = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    modifier = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.PROTECT,
        verbose_name="修改人",
        related_name="permission_modifier",
    )
    status = models.BooleanField(default=True, verbose_name="当前状态")

    class Meta:
        verbose_name_plural = "用户权限表"

    def __str__(self):
        return "{} - {} - {}".format(self.id, self.name, self.code)


# 参数设置
class config(BaseModel):
    # 基础信息
    name = models.CharField(max_length=32, null=True, blank=True, verbose_name="系统名称")
    logo_file = models.FileField(upload_to='app/static', null=True, blank=True, verbose_name="系统logo")
    desc = models.CharField(max_length=128, null=True, blank=True, verbose_name="版权信息")

    # 其他信息
    status = models.BooleanField(default=False, verbose_name="状态")
    created_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.PROTECT,
                                   verbose_name="创建人", related_name='parameter_created_by')
    modified_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.PROTECT,
                                    verbose_name="修改人", related_name='parameter_modifier')


    def __str__(self):
        return "{} - {}".format(self.name, self.logo_file)

    class Meta:
        verbose_name = "系统设置"
        verbose_name_plural = "系统设置"




# 部门管理
class Department(BaseModel):
    SYSTEM = (
        ("all", "全系统"),
    )
    belong_system = models.CharField(
        max_length=16, choices=SYSTEM, default="cangchu", verbose_name="所属系统"
    )
    parent = models.ForeignKey(
        "self",
        null=True,
        blank=True,
        related_name="department_child",
        on_delete=models.PROTECT,
        verbose_name="所属父级部门",
    )
    name = models.CharField(max_length=64, verbose_name="部门名称", null=True, blank=True)
    code = models.CharField(
        max_length=32, null=True, blank=True, verbose_name="部门code码"
    )
    color = models.CharField(max_length=32, null=True, blank=True, verbose_name="专用色调")
    describe = models.CharField(
        max_length=256, null=True, blank=True, verbose_name="部门描述"
    )

    create_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        null=True,
        blank=True,
        verbose_name="创建人",
        on_delete=models.SET_NULL,
        related_name="dep_create_by",
    )
    update_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        null=True,
        blank=True,
        verbose_name="编辑人",
        on_delete=models.SET_NULL,
        related_name="dep_update_by",
    )

    def __str__(self):
        return "{} - {} - {}".format(self.id, self.name, self.code)

    class Meta:
        verbose_name = "部门管理"
        verbose_name_plural = "部门管理"


# 角色表
class Role(models.Model):
    SYSTEM = (
        ("all", "全系统"),
    )
    belong_system = models.CharField(
        max_length=16, choices=SYSTEM, default="cangchu", verbose_name="所属系统"
    )

    parent = models.ForeignKey(
        "self",
        null=True,
        blank=True,
        related_name="children",
        on_delete=models.PROTECT,
        verbose_name="所属父级角色",
    )
    code = models.CharField(max_length=255, unique=True, verbose_name="角色唯一CODE代码")
    name = models.CharField(max_length=64, null=True, blank=True, verbose_name="角色名称")
    intro = models.CharField(max_length=255, null=True, blank=True, verbose_name="角色介绍")
    role_permission = models.ManyToManyField(
        Permission, blank=True, verbose_name="选择权限"
    )

    # 状态信息
    creator = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        null=True,
        blank=True,
        on_delete=models.PROTECT,
        verbose_name="创建人",
        related_name="role_creator",
    )
    created = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    modifiered = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    modifier = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        null=True,
        blank=True,
        on_delete=models.PROTECT,
        verbose_name="修改人",
        related_name="role_modifier",
    )
    status = models.BooleanField(default=True, verbose_name="当前状态")

    class Meta:
        verbose_name_plural = "角色表 "

    def __str__(self):
        return "{} - {} - {}".format(self.id, self.name, self.code)


class ConsumerManager(BaseUserManager):
    def change_password(self, username, old_password, new_password1):
        if not username:
            raise ValueError("必须填写登录账号")

        consumer = authenticate(username=username, password=old_password)
        if consumer is not None:
            consumer.set_password(new_password1)
            consumer.save(using=self._db)
        return consumer

    def create_user(self, username, password=None):
        if not username:
            raise ValueError("必须填写登录账号")

        consumer = self.model(username=username)

        consumer.set_password(password)
        consumer.save(using=self._db)
        return consumer

    def create_superuser(self, username, password):
        consumer = self.create_user(username=username, password=password)
        consumer.is_admin = True
        consumer.is_staff = True
        consumer.is_superuser = True
        consumer.save(using=self._db)
        return consumer

    def bluk_create_user(self, username, status, is_staff, password):
        consumer = self.create_user(username=username, password=password)
        consumer.status = status
        consumer.is_staff = is_staff
        consumer.is_admin = False

        consumer.is_superuser = False
        consumer.save(using=self._db)
        return consumer


# 用户信息表
class Consumer(AbstractBaseUser, PermissionsMixin):
    SYSTEM = (
        ("all", "全系统"),
    )
    belong_system = models.CharField(
        max_length=16, choices=SYSTEM, default="cangchu", verbose_name="所属系统"
    )

    # 登录信息
    username = models.CharField(
        max_length=128,
        unique=True,
        default="admin",
        verbose_name="登录账号",
        help_text="如手机号、邮箱等",
    )
    category = models.CharField(
        max_length=32, choices=USER_TYPE, default="common", verbose_name="账号类别"
    )

    # 基本信息
    name = models.CharField(max_length=128, verbose_name="用户姓名")
    mobile = models.CharField(
        max_length=128, default="", null=True, blank=True, verbose_name="联系电话"
    )
    sex = models.CharField(
        max_length=32, choices=SEX, default="male", verbose_name="性别"
    )
    email = models.EmailField(
        max_length=255, unique=True, null=True, blank=True, verbose_name="邮箱"
    )
    avator = models.CharField(
        max_length=128, null=True, blank=True, verbose_name="用户头像"
    )
    belong_role = models.ForeignKey(
        Role,
        blank=True,
        null=True,
        on_delete=models.CASCADE,
        related_name="belong_role_account",
        verbose_name="用户所属角色",
    )
    belong_department = models.ForeignKey(
        Department,
        blank=True,
        null=True,
        on_delete=models.CASCADE,
        related_name="belong_department_account",
        verbose_name="所属部门",
    )
    salt = models.CharField(max_length=64, null=True, blank=True, verbose_name="密码加盐")
    is_delete = models.BooleanField(default=False, verbose_name="是否删除")

    # 状态信息
    status = models.BooleanField(default=True, verbose_name="是否启用")
    is_active = models.BooleanField(default=True, verbose_name="是否激活")
    is_staff = models.BooleanField(default=False, verbose_name="工作人权限")
    is_admin = models.BooleanField(default=False, verbose_name="超级用户权限")
    date_joined = models.DateTimeField(default=timezone.now, verbose_name="创建日期")

    objects = ConsumerManager()

    USERNAME_FIELD = "username"
    REQUIRED_FIELDS = []

    class Meta:
        verbose_name_plural = "用户信息表"

    def __str__(self):
        return "{0} {1}".format(self.name, self.mobile)

    @property
    def get_group_name(self):
        if self.groups.exists():
            return self.groups.all()[0]
        return [i.name for i in self.groups.all()]


# 菜单信息
class StorageMenu(models.Model):
    SYSTEM = (
        ("all", "全系统"),
    )

    belong_sys = models.CharField(
        max_length=32, choices=SYSTEM, default="cangchu", verbose_name="系统类别"
    )
    parentPath = models.ForeignKey(
        "self",
        null=True,
        blank=True,
        related_name="children",
        on_delete=models.PROTECT,
        verbose_name="上级菜单",
    )
    menuName = models.CharField(max_length=64, verbose_name="菜单名称")
    icon = models.CharField(max_length=64, null=True, blank=True, verbose_name="菜单图标")
    code = models.CharField(max_length=32, null=True, blank=True, verbose_name="菜单编码")
    order = models.IntegerField(null=True, blank=True, verbose_name="排序")
    menuUrl = models.CharField(
        max_length=64, null=True, blank=True, verbose_name="菜单地址"
    )
    routeName = models.CharField(
        max_length=64, null=True, blank=True, verbose_name="路由名称"
    )
    localFilePath = models.CharField(
        max_length=64, null=True, blank=True, verbose_name="本地文件地址"
    )
    badge = models.CharField(
        max_length=64, null=True, blank=True, verbose_name="菜单中的提示信息"
    )

    isSingle = models.BooleanField(default=False, verbose_name="是否是一级标题")
    cacheable = models.BooleanField(default=True, verbose_name="是否缓存")
    is_hidden = models.BooleanField(default=True, verbose_name="是否隐藏")
    affix = models.BooleanField(default=True, verbose_name="是否固定")
    status = models.BooleanField(default=True, verbose_name="是否启用")

    belong_role = models.ManyToManyField(
        "Role",
        blank=True,
        related_name="menu_permission_belong_role",
        verbose_name="关联用户角色",
        help_text="关联用户角色",
    )
    belong_department = models.ManyToManyField(
        "Department",
        blank=True,
        related_name="menu_permission_belong_department",
        verbose_name="关联部门",
        help_text="关联部门",
    )

    remark = models.CharField(max_length=64, null=True, blank=True, verbose_name="备注")

    created = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    modifiered = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    def __str__(self):
        return "{}".format(self.menuName)

    class Meta:
        verbose_name_plural = "菜单表"
        verbose_name = "菜单表"



# 图片地址
# class ImageFileAddress(BaseModel):
#     file = models.ImageField(
#         upload_to="images", null=True, blank=True, verbose_name="上传图片地址"
#     )
#
#     @property
#     def image_urls(self):
#         return str(self.file.url)
#
#     class Meta:
#         verbose_name = "图片地址"
#         verbose_name_plural = "图片地址"


# 视频地址
class VideoFileAddres(BaseModel):
    file = models.FileField(
        upload_to="videos/", null=True, blank=True, verbose_name="上传视频地址"
    )

    @property
    def video_urls(self):
        return str(self.file.url)

    class Meta:
        verbose_name = "视频地址"
        verbose_name_plural = "视频地址"